home *** CD-ROM | disk | FTP | other *** search
/ MIDICraft's MIDINET CD-ROM / MIDICraft's MIDINET CD-ROM.iso / DOSUTILS / KORGI3 / SENDSYX.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1996-11-03  |  9.9 KB  |  550 lines

  1. // sysex: (c) Günter Nagler 1996
  2. #include <stdio.h>
  3. #include <ctype.h>
  4. #include <string.h>
  5. #include <stdlib.h>
  6. #include <conio.h>
  7. #include "filei3.hpp"
  8. #include "sndcard.hpp"
  9.  
  10. static char* version = "sendsyx v1.0 by Günter Nagler (" __DATE__ ")";
  11.  
  12. Soundcard* card = 0;
  13.  
  14. char* inputname = 0;
  15. int echo = 0;
  16. long skip = 0;
  17. long count = 0x7fffffffL;
  18. int isbinary = 0;
  19. int encode = 0;
  20. int binaryencode = 0;
  21. unsigned char dumb[8];
  22. unsigned char byte[7];
  23. int bytelen = 0;
  24. long sum = 0;
  25. int reply = 1;
  26.  
  27. int escape()
  28. {
  29. static int esc = 0;
  30.  
  31.   if (esc)
  32.     return 1;
  33.   while (kbhit())
  34.     if (getch() == 27)
  35.       return esc = 1;
  36.   return 0;
  37. }
  38.  
  39. void checkreply()
  40. {
  41. #define RETRY   100
  42.  
  43.   printf("waiting for reply...");
  44.  
  45.   unsigned char buf[1024], data;
  46.  
  47.   int insysex = 0;
  48.  
  49.   card->startinput();
  50.   for (int i = 0; i < RETRY; i++)
  51.   {
  52.     int len = card->hear(buf, sizeof(buf));
  53.     if (len <= 0)
  54.     {
  55.        if (escape())
  56.      break;
  57.        continue;
  58.     }
  59.     for (int j = 0; j < len; j++)
  60.     {
  61.       data = buf[j];
  62.       if (insysex)
  63.       {
  64.     printf(" %02x", data);  // should be F7
  65.     if (data & 0x80)
  66.       break;
  67.       }
  68.       else
  69.       {
  70.     if (data == 0xf0)
  71.     {
  72.       printf("\nreply: %02x", data);
  73.       insysex = 1;
  74.     }
  75.     else
  76.       ;
  77.  
  78.     // ignore
  79.       }
  80.     }
  81.     if (j < len)
  82.       break;
  83.   }
  84.   card->stopinput();
  85.   if (insysex)
  86.     printf("\n");
  87.   else
  88.     printf(" no reply\n");
  89. }
  90.  
  91. void checkresponse()
  92. {
  93. #define RESPONSE_RETRY   1000
  94.  
  95.   card->startinput();
  96.  
  97.   unsigned char data;
  98.  
  99.   for (long i = 0; i < RESPONSE_RETRY; i++)
  100.   if (card->hear(&data, 1))
  101.      break;
  102.   if (i == RETRY)
  103.     fprintf(stderr, "Warning: no response. Transfer might not work.\n");
  104.   card->stopinput();
  105. }
  106.  
  107. int flushbytes()
  108. {
  109.   if (bytelen == 0)
  110.     return 1;
  111.   int dumblen = code7to8(byte, bytelen, dumb);
  112.   bytelen = 0;
  113.   sum += dumblen;
  114.   return card->play(dumb, dumblen) == dumblen;
  115. }
  116.  
  117. int sendbyte(unsigned char data)
  118. {
  119.   if (encode)
  120.   {
  121.     // add to encode buffer
  122.     byte[bytelen++] = data;
  123.     if (bytelen == 7)
  124.       return flushbytes();
  125.     return 1;
  126.   }
  127.   else if (bytelen > 0) // buffer contains data to encode
  128.   {
  129.     if (!flushbytes())
  130.       return 0;
  131.   }
  132.   sum ++;
  133.   if (card->play(&data, 1) != 1)
  134.   {
  135.     fprintf(stderr, "could not send byte %s\n", data);
  136.     return 0;
  137.   }
  138.   if (echo)
  139.     printf("%02X ", data);
  140.   return 1;
  141. }
  142.  
  143. int sendbytes(unsigned char* data, int len)
  144. {
  145.   if (!data)
  146.     return 0;
  147.   while (len-- > 0)
  148.   {
  149.     if (!sendbyte(*data++))
  150.       return 0;
  151.   }
  152.   return 1;
  153. }
  154.  
  155. int sendcontrol(unsigned char ctrl, unsigned char val)
  156. {
  157. unsigned char data[3];
  158.  
  159.   data[0] = 0xb0;
  160.   data[1] = ctrl;
  161.   data[2] = val;
  162.   for (int c = 0; c < 16; c++)
  163.   {
  164.     sum += 3;
  165.     if (!card->play(data, 3))
  166.       return 0;
  167.     data[0]++;
  168.   }
  169.   return 1;
  170. }
  171.  
  172. int testbinary(FILE* f)
  173. {
  174. long oldpos = ftell(f);
  175. int c;
  176.  
  177.   while ((c = fgetc(f)) != EOF)
  178.   {
  179.     if (c < ' ' && !isspace(c))
  180.       break;
  181.     if (c >= 0x80)
  182.       break;
  183.   }
  184.   fseek(f, oldpos, SEEK_SET);
  185.   if (c == EOF)
  186.     return 0;
  187.   else
  188.     return 1;
  189. }
  190.  
  191. int get(FILE* inf, char* &inbuf)
  192. {
  193.   if (inbuf)
  194.   {
  195.     if (*inbuf == 0)
  196.       return EOF;
  197.     else
  198.       return *inbuf++;
  199.   }
  200.   if (inf)
  201.     return fgetc(inf);
  202.   return EOF;
  203. }
  204.  
  205. int sendsysex(char* filename);
  206.  
  207. int hexval(int c)
  208. {
  209.   if (isdigit(c))
  210.     return c - '0';
  211.   else if (isxdigit(c))
  212.     return toupper(c) - 'A' + 10;
  213.   else
  214.     return -1;
  215. }
  216.  
  217. int hexval(char* s)
  218. {
  219. int v1, v2;
  220.  
  221.   if (!s || (v1 = hexval(*s)) < 0)
  222.     return -1;
  223.   if (s[1] == 0)
  224.     return v1;
  225.   if (s[2])
  226.     return -1;
  227.   v2 = hexval(s[1]);
  228.   if (v2 < 0)
  229.     return -1;
  230.   return (v1 << 4) + v2;
  231. }
  232.  
  233. int sendtextsyx(FILE* f, char* buf)
  234. {
  235.     int c = get(f, buf);
  236.     // assume text
  237.     while (c != EOF)
  238.     {
  239.       if (escape())
  240.     break;
  241.       if (isspace(c))
  242.     ;
  243.       else if (c == '/')
  244.       {
  245.     c = get(f, buf);
  246.     if (c == '/')
  247.     {
  248.       while (c != EOF && c != '\n')
  249.         c = get(f, buf);
  250.     }
  251.     else
  252.     {
  253.       fprintf(stderr, "invalid character / ignored\n");
  254.       continue;
  255.     }
  256.       }
  257.       else
  258.       {
  259.       char ident[128];
  260.       int len = 0;
  261.     // keyword?
  262.  
  263.     while (c != EOF && !isspace(c))
  264.     {
  265.       if (len < sizeof(ident)-1)
  266.         ident[len++] = c;
  267.       c = get(f, buf);
  268.     }
  269.     ident[len] = '\0';
  270.  
  271.     int value;
  272.  
  273.     if ((value = hexval(ident)) >= 0)
  274.     {
  275.       if (!sendbyte(value))
  276.          break;
  277.       continue;
  278.     }
  279.  
  280.     if (stricmp(ident, "gmon") == 0)
  281.     {
  282.       if (!sendbytes("\xF0\x7E\x7F\x09\x01\xF7", 6))
  283.        break;
  284.     }
  285.     else if (stricmp(ident, "identify") == 0)
  286.     {
  287.       if (!sendbytes("\xf0\x7e\x00\x06\x01\xf7", 6))
  288.        break;
  289.     }
  290.     else if (stricmp(ident, "xgon") == 0)
  291.     {
  292.       if (!sendbytes("\xF0\x08\x43\x10\x4c\x00\x00\x7e\x00\xf7", 10))
  293.        break;
  294.     }
  295.     else if (stricmp(ident, "gson") == 0)
  296.     {
  297.       if (!sendbytes("\xF0\x0a\x41\x10\x42\x12\x40\x00\x7f\x00\x41\xf7", 12))
  298.        break;
  299.     }
  300.     else if (stricmp(ident, "gsoff") == 0)
  301.     {
  302.       if (!sendbytes("\xF0\x0a\x41\x10\x42\x12\x40\x00\x7f\x7f\x42\xf7", 12))
  303.        break;
  304.     }
  305.     else if (stricmp(ident, "localon") == 0)
  306.     {
  307.       if (!sendcontrol(0x7a, 127))
  308.        break;
  309.     }
  310.     else if (stricmp(ident, "localoff") == 0)
  311.     {
  312.       if (!sendcontrol(0x7a, 0))
  313.        break;
  314.     }
  315.     else if (stricmp(ident, "notesoff") == 0)
  316.     {
  317.       if (!sendcontrol(0x7b, 0))
  318.        break;
  319.     }
  320.     else if (stricmp(ident, "omnioff") == 0)
  321.     {
  322.       if (!sendcontrol(0x7c, 0))
  323.        break;
  324.     }
  325.     else if (stricmp(ident, "omnion") == 0)
  326.     {
  327.       if (!sendcontrol(0x7d, 0))
  328.        break;
  329.     }
  330.     else if (stricmp(ident, "polyoff") == 0)
  331.     {
  332.       if (!sendcontrol(0x7e, 0))
  333.        break;
  334.     }
  335.     else if (stricmp(ident, "polyon") == 0)
  336.     {
  337.       if (!sendcontrol(0x7f, 0))
  338.        break;
  339.     }
  340.     else if (stricmp(ident, "sox") == 0)
  341.     {
  342.       if (!sendbyte(0xf0))
  343.        break;
  344.     }
  345.     else if (stricmp(ident, "eox") == 0)
  346.     {
  347.       if (!sendbyte(0xf7))
  348.        break;
  349.     }
  350.     else
  351.     {
  352.       // try if it is a filename
  353.       FILE* f = fopen(ident, "rb");
  354.       if (f)
  355.       {
  356.         fclose(f);
  357.         sendsysex(ident);
  358.         continue;
  359.       }
  360.       else if (strchr(ident, '.'))
  361.         perror(ident);
  362.       else
  363.         fprintf(stderr,"unknown identifier %s ignored\n", ident);
  364.       return 0;
  365.     }
  366.     continue;
  367.       }
  368.       c = get(f, buf);
  369.     }
  370.     return 1;
  371. }
  372.  
  373. int sendsysex(char* filename)
  374. {
  375.   FILE* f = fopen(filename, "rb");
  376.   if (!f)
  377.   {
  378.     perror(filename);
  379.     return 1;
  380.   }
  381.   int looksbinary = isbinary || testbinary(f);
  382.   int c;
  383.  
  384.   if (!looksbinary)
  385.   {
  386.     return sendtextsyx(f, 0) != 0;
  387.   }
  388.   else
  389.   {
  390.     if (count <= 0)
  391.       count = 0x7fffffffL;
  392.  
  393.     if (skip < 0)
  394.       skip = 0;
  395.  
  396.     encode = binaryencode;
  397.     if (encode && echo)
  398.       printf("<encoded data> ");
  399.     fseek(f, skip, SEEK_SET);
  400.     skip = 0;
  401.     c = fgetc(f);
  402.     // assume binary
  403.     while (c != EOF && count > 0)
  404.     {
  405.       if (escape())
  406.     break;
  407.       count--;
  408.       if (!sendbyte(c))
  409.     break;
  410.       c = fgetc(f);
  411.     }
  412.     encode = 0;
  413.     count = 0;
  414.   }
  415.  
  416.   fclose(f);
  417.   return 0;
  418. }
  419.  
  420. int main(int argc, char** argv)
  421. {
  422.   argc--; argv++;
  423.  
  424.   int ret = 0;
  425.  
  426.   if (argc == 0)
  427.   {
  428.      printf("%s\n", version);
  429.      printf("usage: sysex [-noreply] [-skip #] [-count #] [-echo] [-enc] [-raw] [hex] [cmd] [file] ...\n");
  430.      printf("-noreply don't wait for a reply\n");
  431.      printf("-skip #  skip bytes of next binary file\n");
  432.      printf("-count # read count bytes of next binary file (default: read till end)\n");
  433.      printf("-echo    echo sent bytes in hexadecimal format\n");
  434.      printf("-enc     dump encode bytes read from binary files\n");
  435.      printf("-raw     do not encode bytes read from binary files\n");
  436.      printf("hex      send byte (e.g. f0 42 a f7)\n");
  437.      printf("cmd      send command (e.g. gmon notesoff ...)\n");
  438.      printf("file     end content of binary or hex file\n");
  439.      printf("All parameters can be used more than once. Text files can contain hex, cmd, file\n");
  440.      printf("-skip,-count,-enc only affect next binary file\n");
  441.      return 1;
  442.   }
  443.  
  444.   card = detect_soundcard();
  445.   if (!card)
  446.   {
  447.     fprintf(stderr, "Could not detect soundcard\n");
  448.     return 1;
  449.   }
  450.  
  451.   checkresponse();
  452.  
  453.   while (argc > 0)
  454.   {
  455.     if (escape())
  456.       break;
  457.     if (**argv == '-')
  458.     {
  459.       if (strnicmp(*argv, "-version", 2) == 0)
  460.       {
  461.     fprintf(stderr, "%s\n", version);
  462.     *argv = 0;
  463.     argc--; argv++;
  464.       }
  465.       if (strnicmp(*argv, "-binary", 2) == 0)
  466.       {
  467.     isbinary = 1;
  468.     argc--; argv++;
  469.     continue;
  470.       }
  471.       if (strnicmp(*argv, "-noreply", 2) == 0)
  472.       {
  473.     reply = 0;
  474.     argc--; argv++;
  475.     continue;
  476.       }
  477.       if (strnicmp(*argv, "-encode", 3) == 0)
  478.       {
  479.     binaryencode = 1;
  480.     argc--; argv++;
  481.     continue;
  482.       }
  483.       if (strnicmp(*argv, "-raw", 2) == 0)
  484.       {
  485.     encode = 0;
  486.     argc--; argv++;
  487.     continue;
  488.       }
  489.       if (strnicmp(*argv, "-echo", 2) == 0)
  490.       {
  491.     echo = 1;
  492.     argc--; argv++;
  493.     continue;
  494.       }
  495.       if (strnicmp(*argv, "-skip", 2) == 0)
  496.       {
  497.     argc--; argv++;
  498.     if (argc == 0 || !isxdigit(**argv))
  499.       fprintf(stderr, "option -skip needs a value\n");
  500.     else
  501.     {
  502.     char* endptr = 0;
  503.  
  504.       skip = strtoul(*argv, &endptr, 0);
  505.       if (endptr && *endptr)
  506.         fprintf(stderr, "%s is not a legal value\n", *argv);
  507.       argc--; argv++;
  508.     }
  509.     continue;
  510.       }
  511.       if (strnicmp(*argv, "-count", 2) == 0)
  512.       {
  513.     argc--; argv++;
  514.     if (argc == 0 || !isxdigit(**argv))
  515.       fprintf(stderr, "option -count needs a value\n");
  516.     else
  517.     {
  518.     char* endptr = 0;
  519.  
  520.       count = strtoul(*argv, &endptr, 0);
  521.       if (endptr && *endptr)
  522.         fprintf(stderr, "%s is not a legal value\n", *argv);
  523.       argc--; argv++;
  524.     }
  525.     continue;
  526.       }
  527.       fprintf(stderr, "invalid option %s\n", *argv);
  528.       argc--; argv++; continue;
  529.     }
  530.     else
  531.     {
  532.     char* arg = *argv++; argc--;
  533.     int arglen = strlen(arg);
  534.  
  535.       if (arglen == 0)
  536.     continue;
  537.       sendtextsyx(0, arg);
  538.     }
  539.   }
  540.  
  541.   if (sum > 0 && reply)
  542.   {
  543.     printf("\n%ld bytes sent, ", sum);
  544.     checkreply();
  545.   }
  546.  
  547.   delete card;
  548.   return ret;
  549. }
  550.